package com.zf.nospring.rocketmq.simple;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;

import java.util.List;

/**
 * 使用 推（Push）模式 的消费，实际上底层是使用 拉（Pull）模式 实现的。
 * rocketmq推荐使用 推（Push）模式。
 */
public class ConsumerPushTest {

    public static void main(String[] args) throws MQClientException {
        // 创建消息消费者, 指定消费者所属的组名。使用 Push模式，是对 Pull 模式的包装
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("no-spring-cg");
        // 指定Nameserver地址
        consumer.setNamesrvAddr("localhost:9876");

        // 设置消费模式：
        // 集群消费：同一条消息只能被消费者组中的一个消费者处理。
        // 广播消费：同一条消息可以被消费者组中的每个消费者至少消费一次。和不同的消费者组可以消费相同的消息相似。
        // 默认是集群模式。
        // 测试发现，只要消费这组中的任何一个消费者设置了 广播模式，那么组中的每个消费者都可以消费到相同的消息，不管其他消费者如何设置
        // consumer.setMessageModel(MessageModel.BROADCASTING);

        // 指定消费者订阅的主题和标签
        consumer.subscribe("test_topic", "*");
        // 使用回调函数处理推送的消息
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> messages, ConsumeConcurrentlyContext context) {
                for (MessageExt message : messages) {
                    System.out.printf("Message：%s, body：%s\n", message, new String(message.getBody()));
                }
                //返回消费状态，表示消费成功
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        // 启动消息消费者
        consumer.start();
        System.out.println("Consumer Started.....");
    }
}
